package com.wp.file.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDate;

@Slf4j
@Component
public class FtpHelper {
    //FTPClient的配置
    @Autowired
    private FtpClientConfig ftpClientConfig;
    //静态的用于在工具类接收自动装配的config
    private static FtpClientConfig ftpConfig;
    //静态的FTPClient
    private static FTPClient ftp;
    //仓库文件名
    private static String StockRoom = "/warehouse";
    //在spring容器初始化的时候执行
    @PostConstruct
    public void setconfig() {
        ftpConfig=ftpClientConfig;
    }

    /**
     * 初始化FTPClient
     * @return
     */
    public static boolean initFtpClient() {
        ftp = new FTPClient();
        try {
            ftp.connect(ftpConfig.host, ftpConfig.port);
            int replyCode = ftp.getReplyCode();
            if(!FTPReply.isPositiveCompletion(replyCode)){
                ftp.disconnect();
                log.warn("FTPServer refused connection,replyCode:{}", replyCode);
                return false;
            }
            if(!ftp.login(ftpConfig.username,ftpConfig.password)){
                log.warn("ftpClient login failed... username is {}; password: {}", ftpConfig.username, ftpConfig.password);
                return false;
            }
            ftp.setBufferSize(10240);//传输流大小
            ftp.setDataTimeout(600000*60);//传输超时时间 1小时
            ftp.setConnectTimeout(600000*60);//传输连接时间 1小时
            ftp.setFileType(FTP.BINARY_FILE_TYPE);//二进制
            ftp.enterLocalPassiveMode();//被动模式
        } catch (IOException e) {
            log.error("create ftp connection failed...", e);
        }
        return true;
    }

    /**
     * 上传文件
     * @param multipartFile
     * @param newName
     * @return
     */
    public static boolean uploadFile(MultipartFile multipartFile,String newName){
        InputStream inputStream =null;
        if(!initFtpClient()){
            return false;
        }
        try {
            //每次初始化之后 默认路径都是/home/user-file 所以不用像以前那样切换
            inputStream= multipartFile.getInputStream();
            log.info("start upload... {}", multipartFile.getOriginalFilename());
            String overPath = ftpConfig.basepath+StockRoom+"/"+ LocalDate.now();
            //                   /home/user-file/warehouse/2023-01-07
            boolean dirSuccess = ftp.changeWorkingDirectory(overPath);
            if(!dirSuccess){
                ftp.makeDirectory(ftpConfig.basepath+StockRoom);// /home/user-file/warehouse
                ftp.makeDirectory(overPath);// /home/user-file/warehouse/2023-01-07
                ftp.changeWorkingDirectory(overPath);
            }
            boolean storeFileFlag = ftp.storeFile(new String(newName.getBytes("GBK"), "iso-8859-1"), inputStream);
            if(storeFileFlag){
                log.info("upload file success! {}", multipartFile.getOriginalFilename());
                return true;
            }
            ftp.logout();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputStream);
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        log.warn("upload file failure! {}", multipartFile.getOriginalFilename());
        return false;
    }

    /**
     * 通过文件流上传office文件
     */
    public static boolean uploadOfficeByStream(InputStream inputStream,String newName){
        //这里的newName实际是file的MD5 name
        if(!initFtpClient()){
            return false;
        }
        try {
            log.info("start upload... office");
            String overPath = ftpConfig.basepath+StockRoom+"/"+ LocalDate.now();
            //                   /home/user-file/warehouse/2023-01-07
            boolean dirSuccess = ftp.changeWorkingDirectory(overPath);
            if(!dirSuccess){
                ftp.makeDirectory(ftpConfig.basepath+StockRoom);// /home/user-file/warehouse
                ftp.makeDirectory(overPath);// /home/user-file/warehouse/2023-01-07
                ftp.changeWorkingDirectory(overPath);
            }
            boolean storeFileFlag = ftp.storeFile(new String(newName.getBytes("GBK"), "iso-8859-1"), inputStream);
            if(storeFileFlag){
                log.info("upload file success! {}", newName);
                return true;
            }
            ftp.logout();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputStream);
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        log.warn("upload file failure! {}", newName);
        return false;
    }

    /**
     * 文件下载
     * @param outputStream
     * @param path
     * @param storename
     * @param displayName
     * @return
     */
    public static boolean downloadFile(OutputStream outputStream,String path,String storename,String displayName) {

        if(!initFtpClient()){
            return false;
        }
        String overPath = ftpConfig.basepath+StockRoom + path+"/"+storename;
        log.info("start download... {}", displayName);


        try {
            boolean retrieveFileFlag = ftp.retrieveFile(new String(overPath.getBytes("GBK"), "iso-8859-1"), outputStream);
            if(retrieveFileFlag){
                log.warn("download file success! {}", displayName);
                return true;
            }
            ftp.logout();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(outputStream);
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        log.warn("download file failure! {}", displayName);
        return false;
    }

}
